package top.lixunda.common.validate.core;

import lombok.extern.slf4j.Slf4j;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @author Xumda
 * @version time:2019/11/19 15:17
 * <p>
 * 验证器，进行实体类参数验证工作
 */
@SuppressWarnings({"WeakerAccess", "InfiniteRecursion", "unused"})
@Slf4j
public abstract class BaseValidatorDTO implements IBaseEntityValidator {

    /**
     * 保存用户自定义验证的验证器
     */
    private static volatile Map<Class, List<StrongValidator>> validatorMap = new ConcurrentHashMap<>(128);

    /**
     * 自定义验证的默认参数
     */
    private static final String DEFAULT_TYPE = "default";

    /**
     * 注解方式验证的验证器
     */
    private static final AnnotationValidator ANNOTATION_VALIDATOR = AnnotationValidator.DEFAULT_VALIDATOR;

    /**
     * 初始化方法
     *
     * @param config Validator构造器
     */
    public void init(ValidatorConfig config) {
    }

    /**
     * 获取验证器进行验证，若验证器为空，会从init方法中初始化验证器
     *
     * @return 验证器列表
     */
    private List<StrongValidator> getValidators() {
        Class clazz = this.getClass();
        List<StrongValidator> list = validatorMap.get(clazz);
        if (list == null) {
            synchronized (BaseValidatorDTO.class) {
                list = validatorMap.get(clazz);
                if (list == null) {
                    ValidatorConfig config = new ValidatorConfig();
                    init(config);
                    validatorMap.put(clazz, (list = config.build()) == null ? (list = new ArrayList<>(8)) : list);
                }
            }
        }
        return list;
    }

    /**
     * 参数验证，只验证用户配置的参数，不验证注解
     *
     * @return 验证结果
     */
    @Override
    public ValidateResult validate() {
        return validate(DEFAULT_TYPE);
    }

    /**
     * 参数验证，只验证用户配置的参数，不验证注解
     *
     * @param type 验证参数
     * @return 验证结果
     */
    @Override
    public ValidateResult validate(String type) {
        if (type == null || "".equals(type)) {
            type = DEFAULT_TYPE;
        }
        ValidateError error;
        for (StrongValidator validator : getValidators()) {
            error = validator.valid(type);
            if (error == null) {
                continue;
            }
            return new ValidateResult().addErrors(error);
        }
        return new ValidateResult();
    }

    /**
     * 注解验证，只验证注解，不验证用户配置的参数
     *
     * @return 验证结果
     */
    @Override
    public ValidateResult validateAnnotation() {
        Field[] fields = this.getClass().getDeclaredFields();
        if (fields == null || fields.length == 0) {
            return new ValidateResult();
        }
        ValidateError error = ANNOTATION_VALIDATOR.validAllField(this);
        return error == null ? new ValidateResult() : new ValidateResult().addErrors(error);
    }

    /**
     * 验证注解和代码，首先验证注解
     *
     * @return 返回验证结果
     */
    @Override
    public ValidateResult validateAll() {
        return validateAll(DEFAULT_TYPE);
    }

    /**
     * 验证注解和代码，首先验证注解
     *
     * @param type 验证参数
     * @return 返回验证结果
     */
    @Override
    public ValidateResult validateAll(String type) {
        if (type == null || "".equals(type)) {
            type = DEFAULT_TYPE;
        }
        return new ValidateResult().addErrors(validateAnnotation().getErrorList()).addErrors(validate(type).getErrorList());
    }

}
